package com.studyweb.service.impl;

import com.studyweb.mapper.FileUploadMapper;
import com.studyweb.pojo.entity.FileUpload;
import com.studyweb.service.FileUploadService;
import com.studyweb.utils.FileUploadUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 文件上传服务实现类
 * 
 * @author StudyWeb Team
 * @since 1.0.0
 */
@Slf4j
@Service
public class FileUploadServiceImpl implements FileUploadService {
    
    @Autowired
    private FileUploadMapper fileUploadMapper;
    
    @Autowired
    private FileUploadUtils fileUploadUtils;
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> uploadFile(MultipartFile file, Long userId) throws Exception {
        return uploadFile(file, userId, null);
    }
    
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> uploadFile(MultipartFile file, Long userId, String module) throws Exception {
        log.info("开始上传文件，用户ID：{}, 文件名：{}", userId, file.getOriginalFilename());
        
        Map<String, Object> uploadResult = null;
        try {
            // 使用工具类上传文件（包含容错机制）
            uploadResult = fileUploadUtils.uploadFile(file);
            log.info("文件上传工具类返回结果: {}", uploadResult);
            
            if (uploadResult == null || !Boolean.TRUE.equals(uploadResult.get("success"))) {
                throw new Exception("文件上传失败：" + uploadResult.get("error"));
            }
            
        } catch (Exception e) {
            log.error("文件上传工具类异常，用户ID：{}, 文件名：{}, 错误：{}", userId, file.getOriginalFilename(), e.getMessage(), e);
            throw new Exception("文件上传失败：" + e.getMessage(), e);
        }
        
        try {
            // 创建文件上传记录
            FileUpload fileUpload = new FileUpload();
            fileUpload.setUserId(userId);
            fileUpload.setOriginalName((String) uploadResult.get("originalName"));
            fileUpload.setFileName((String) uploadResult.get("fileName"));
            fileUpload.setFilePath((String) uploadResult.get("filePath"));
            fileUpload.setFileSize((Long) uploadResult.get("fileSize"));
            fileUpload.setFileType((String) uploadResult.get("fileType"));
            fileUpload.setFileExt((String) uploadResult.get("fileExtension"));
            fileUpload.setAccessUrl((String) uploadResult.get("accessUrl"));
            fileUpload.setUploadMethod((String) uploadResult.get("uploadMethod")); // 添加上传方式
            fileUpload.setModule(module); // 设置模块
            fileUpload.setStatus(1);
            fileUpload.setCreateTime(LocalDateTime.now());
            fileUpload.setUpdateTime(LocalDateTime.now());
            
            // 保存到数据库
            int result = fileUploadMapper.insert(fileUpload);
            if (result <= 0) {
                throw new Exception("保存文件记录失败");
            }
            
            // 返回结果，包含上传方式信息
            Map<String, Object> response = new HashMap<>();
            response.put("fileId", fileUpload.getFileId());
            response.put("originalName", fileUpload.getOriginalName());
            response.put("fileName", fileUpload.getFileName());
            response.put("accessUrl", fileUpload.getAccessUrl());
            response.put("uploadMethod", fileUpload.getUploadMethod()); // 添加上传方式到返回结果
            
            log.info("文件上传完成，用户ID：{}, 文件ID：{}, 文件名：{}", userId, fileUpload.getFileId(), fileUpload.getOriginalName());
            return response;
            
        } catch (Exception e) {
            log.error("保存文件记录异常，用户ID：{}, 文件名：{}, 错误：{}", userId, file.getOriginalFilename(), e.getMessage(), e);
            throw new Exception("保存文件记录失败：" + e.getMessage(), e);
        }
    }
    
    @Override
    public FileUpload getFileById(Long fileId) {
        if (fileId == null) {
            return null;
        }
        return fileUploadMapper.selectById(fileId);
    }
    
    @Override
    public List<FileUpload> getFilesByUserId(Long userId) {
        if (userId == null) {
            return null;
        }
        return fileUploadMapper.selectByUserId(userId);
    }
    
    @Override
    public List<FileUpload> getAllFiles() {
        return fileUploadMapper.selectAll();
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteFile(Long fileId, Long userId) {
        if (fileId == null || userId == null) {
            return false;
        }
        
        try {
            // 查询文件记录
            FileUpload fileUpload = fileUploadMapper.selectById(fileId);
            if (fileUpload == null) {
                log.warn("文件记录不存在，文件ID：{}", fileId);
                return false;
            }
            
            // 检查权限（只能删除自己上传的文件）
            if (!fileUpload.getUserId().equals(userId)) {
                log.warn("无权限删除文件，文件ID：{}, 用户ID：{}, 文件所有者：{}", fileId, userId, fileUpload.getUserId());
                return false;
            }
            
            // 删除物理文件（根据记录的上传方式删除）
            boolean physicalDeleted = fileUploadUtils.deleteFile(fileUpload.getFilePath(), fileUpload.getUploadMethod());
            if (!physicalDeleted) {
                log.warn("删除物理文件失败，文件路径：{}, 上传方式：{}", fileUpload.getFilePath(), fileUpload.getUploadMethod());
            }
            
            // 删除数据库记录
            int result = fileUploadMapper.deleteById(fileId);
            boolean success = result > 0;
            
            if (success) {
                log.info("文件删除成功，文件ID：{}", fileId);
            } else {
                log.error("文件删除失败，文件ID：{}", fileId);
            }
            
            return success;
            
        } catch (Exception e) {
            log.error("删除文件异常，文件ID：{}, 用户ID：{}, 错误：{}", fileId, userId, e.getMessage(), e);
            return false;
        }
    }
    
    @Override
    public List<FileUpload> getFilesByCondition(Long userId, String fileType, Integer status, String module) {
        return fileUploadMapper.selectByCondition(userId, fileType, status, module);
    }
    
    @Override
    public boolean fileExists(Long fileId) {
        if (fileId == null) {
            return false;
        }
        
        FileUpload fileUpload = fileUploadMapper.selectById(fileId);
        if (fileUpload == null) {
            return false;
        }
        
        // 检查物理文件是否存在
        return fileUploadUtils.fileExists(fileUpload.getFilePath());
    }
    
    @Override
    public byte[] getFileContent(Long fileId) {
        if (fileId == null) {
            log.warn("文件ID为空");
            return null;
        }
        
        try {
            // 获取文件信息
            FileUpload fileUpload = fileUploadMapper.selectById(fileId);
            if (fileUpload == null) {
                log.warn("文件记录不存在，文件ID：{}", fileId);
                return null;
            }
            
            log.info("开始获取文件内容，文件ID：{}, 文件路径：{}, 访问URL：{}", fileId, fileUpload.getFilePath(), fileUpload.getAccessUrl());
            
            // 获取文件内容
            byte[] content = fileUploadUtils.getFileContent(fileUpload.getFilePath());
            if (content == null) {
                log.error("文件内容获取失败，文件ID：{}, 文件路径：{}, 访问URL：{}", fileId, fileUpload.getFilePath(), fileUpload.getAccessUrl());
                return null;
            }
            
            log.info("文件内容获取成功，文件ID：{}, 文件大小：{} bytes", fileId, content.length);
            return content;
            
        } catch (Exception e) {
            log.error("获取文件内容异常，文件ID：{}, 错误详情：{}", fileId, e.getMessage(), e);
            return null;
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int batchDeleteFiles(List<Long> fileIds, Long userId) {
        if (fileIds == null || fileIds.isEmpty() || userId == null) {
            return 0;
        }
        
        int successCount = 0;
        
        try {
            for (Long fileId : fileIds) {
                if (fileId != null) {
                    // 查询文件记录
                    FileUpload fileUpload = fileUploadMapper.selectById(fileId);
                    if (fileUpload != null && fileUpload.getUserId().equals(userId)) {
                        // 删除物理文件（根据记录的上传方式删除）
                        boolean physicalDeleted = fileUploadUtils.deleteFile(fileUpload.getFilePath(), fileUpload.getUploadMethod());
                        if (!physicalDeleted) {
                            log.warn("删除物理文件失败，文件路径：{}, 上传方式：{}", fileUpload.getFilePath(), fileUpload.getUploadMethod());
                        }
                        
                        // 删除数据库记录
                        int result = fileUploadMapper.deleteById(fileId);
                        if (result > 0) {
                            successCount++;
                            log.info("文件删除成功，文件ID：{}", fileId);
                        } else {
                            log.error("文件删除失败，文件ID：{}", fileId);
                        }
                    } else {
                        log.warn("文件不存在或无权限删除，文件ID：{}, 用户ID：{}", fileId, userId);
                    }
                }
            }
            
            log.info("批量删除完成，用户ID：{}, 总数：{}, 成功：{}", userId, fileIds.size(), successCount);
            return successCount;
            
        } catch (Exception e) {
            log.error("批量删除文件异常，用户ID：{}, 错误：{}", userId, e.getMessage(), e);
            throw new RuntimeException("批量删除文件失败", e);
        }
    }
    
    @Override
    public Map<String, Object> getUserFileStats(Long userId) {
        Map<String, Object> stats = new HashMap<>();
        
        if (userId == null) {
            stats.put("totalFiles", 0);
            stats.put("totalSize", 0L);
            stats.put("totalSizeFormatted", "0 B");
            return stats;
        }
        
        try {
            List<FileUpload> files = fileUploadMapper.selectByUserId(userId);
            
            int totalFiles = files.size();
            long totalSize = files.stream().mapToLong(FileUpload::getFileSize).sum();
            String totalSizeFormatted = fileUploadUtils.formatFileSize(totalSize);
            
            stats.put("totalFiles", totalFiles);
            stats.put("totalSize", totalSize);
            stats.put("totalSizeFormatted", totalSizeFormatted);
            
            // 按文件类型统计
            Map<String, Integer> typeStats = new HashMap<>();
            for (FileUpload file : files) {
                String fileExt = file.getFileExt();
                if (fileExt != null) {
                    typeStats.put(fileExt, typeStats.getOrDefault(fileExt, 0) + 1);
                }
            }
            stats.put("typeStats", typeStats);
            
        } catch (Exception e) {
            log.error("获取用户文件统计异常，用户ID：{}, 错误：{}", userId, e.getMessage(), e);
            stats.put("totalFiles", 0);
            stats.put("totalSize", 0L);
            stats.put("totalSizeFormatted", "0 B");
        }
        
        return stats;
    }
}